package com.yonyou.pmclouds.siteinspection.filter;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;

/**
 * 校验检查记录中的测量数据输入格式是否为数字
 * @author zhangzhonghao
 */

@Slf4j
public class MeasureDataRequestWrapper extends HttpServletRequestWrapper {

    private String FIELD_INSPECT_ITEMS = "inspectitems";

    private String FIELD_DATA = "datas";

    private String FIELD_CHECK_ITEM = "checkitem";

    private final String body;

    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    public MeasureDataRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder sb = new StringBuilder();
        String line;
        BufferedReader reader = request.getReader();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        body = sb.toString();

    }

    @Override
    public Enumeration<String> getParameterNames() {
        return super.getParameterNames();
    }

    @Override
    public String[] getParameterValues(String name) {
        return super.getParameterValues(name);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public void checkMeasureData() throws ServletException {
        StringBuilder errorBuilder = new StringBuilder();
        JSONObject siteObject = JSONObject.parseObject(body);

        if(siteObject == null){
            return;
        }
        JSONArray inspectJOA = siteObject.getJSONArray(FIELD_INSPECT_ITEMS);
        if(inspectJOA == null || inspectJOA.size() <= 0){
            return;
        }

        for (int i = 0; i < inspectJOA.size(); i++) {
            JSONObject inspectJO = inspectJOA.getJSONObject(i);
            JSONArray datasJOA = inspectJO.getJSONArray(FIELD_DATA);
            if(datasJOA == null || datasJOA.size() <= 0){
                continue;
            }
            String checkItemName = inspectJO.getString(FIELD_CHECK_ITEM);
            StringBuilder errorData = new StringBuilder();
            for (Object data : datasJOA) {
                if (data != null && StringUtils.isNotEmpty(String.valueOf(data)) && !isNumber(String.valueOf(data))) {
                    errorData.append(",").append(data);
                }
            }
            if (StringUtils.isNotEmpty(errorData.toString())) {
                errorData = new StringBuilder(errorData.substring(1));
                errorBuilder.append("[").append(checkItemName).append(":").append(errorData).append("]");
            }
        }
        if (StringUtils.isNotEmpty(errorBuilder.toString())) {
            String errorInfo = "如下检查记录测量数据输入格式不符，需重新填写：" + errorBuilder.toString();
            throw new ServletException(errorInfo);
        }


    }

    private boolean isNumber(String string) {
        String reg = "^[0-9]+(.[0-9]+)?$";
        return string.matches(reg);
    }

}
